import { goBack, goto } from '$utils/intercept';
import { createMessage } from '$components/basic/message';
import { persistentWritable } from '$utils/persist';
import alova from '$utils/request';
import { get, type Writable } from 'svelte/store';
import { throttle } from 'lodash-es';
// import { to } from '$utils/awaitTo';

type UserLoginParams = {
	username: string;
	password: string;
};

const getDefaultUser = () => ({
	name: '',
	avatar: '',
	email: '',
	token: '',
	id: '',
	role: '',
	permissions: [],
	introduction: '',
	phone: '',
	status: '',
	lastLoginIp: '',
	lastLoginTime: '',
	createdAt: '',
	updatedAt: ''
});

export type AccountInfo = { time: number; data: null | IObject };

const useAccountStore = () => {
	const account = persistentWritable<AccountInfo>('account', {
		time: new Date().getTime(),
		data: null
	});

	const setAccount = (value: IObject, clear?: boolean) => {
		if (clear) return account.set({ time: new Date().getTime(), data: null });
		account.set({ time: new Date().getTime(), data: value });
	};

	const initAccountData = (callback: () => Promise<unknown> | undefined) => {
		const curTime = new Date().getTime();
		const info = get(account);

		if (info.time - curTime > 1000 * 60 * 30 || info.data === null) {
			// TODO: 获取用户信息
			// const countries = persistentWritable<>('countries', []);
			callback()?.then((res) => {
				const { code, data } = res as unknown as API.ResOp;
				if (code === 1) setAccount(data);
				else createMessage({ message: 'get Country list fail', type: 'danger' });
			});
			return true;
		}

		return false;
	};

	return {
		account,
		setAccount,
		initAccountData
	};
};

export const useUserstore = () => {
	const token = persistentWritable<string>('token', '' /* 默认空字符 */);
	const time = persistentWritable<number>('token:init', 0);
	const userInfo = persistentWritable('user', getDefaultUser());
	// const ipPosition: string = getWritable('ip', ''); // TODO: 获取ip位置

	const setToken = (_token: string) => {
		token.set(_token);
		time.set(new Date().getTime());
	};

	const clearLoginState = () => {
		token.set('');
		time.set(0);
		userInfo.set({});
		createMessage({ message: 'logout success', type: 'success' });
		goto('/account');
	};

	const login = async (params: UserLoginParams, isDialog: boolean = true) => {
		const message = createMessage({ loading: true, type: 'light', message: 'loading...' });
		// TODO: 登录
		const res = (await alova.Post('/member/login', params)) as unknown as API.ResOp;
		if (res.code !== 1) {
			message.update_loading_to_error(res.message);
			return;
		}
		message.update_loading_to_success('login success');
		const { token, ...rest } = res.data;

		setToken(token as string);
		userInfo.set(rest);

		// redirect(301, backUrl);
		goBack(); // TODO: 登录后跳转
		// userMethodInstance.finally(afterLogin);

		// userMethodInstance.then((res) => {
		// 	console.log(res);
		// });
	};

	const afterLogin = async () => {
		// TODO: 登录后
	};

	const refreshLogin = async () => {
		// TODO: 刷新用户信息
		alova.Get('/member/refresh').then((res) => {
			const { code, data } = res as unknown as API.ResOp;
			if (code === 1 || Number(code) == 200) {
				userInfo.set(data.token);
				time.set(new Date().getTime());
			}
		});
	};

	return {
		token,
		userInfo,
		time,
		login,
		setToken,
		afterLogin,
		refreshLogin,
		clearLoginState,
		...useAccountStore()
	};
};

export type UserStoreType = {
	token: Writable<string>;
	userInfo: Writable<unknown>;
	time: Writable<number>;
	login: (params: UserLoginParams, isDialog?: boolean) => Promise<void>;
	setToken: (_token: string) => void;
	afterLogin: () => Promise<unknown>;
	refreshLogin: () => Promise<void>;
	clearLoginState: () => void;

	account: Writable<AccountInfo>;
	setAccount: (value: IObject) => void;
	initAccountData: () => void;
};

export const refreshUserState = () => {
	let instance: NodeJS.Timeout;
	const store = useUserstore() as unknown as UserStoreType;
	const refresh = () => {
		if (instance) clearInterval(instance);
		console.log('listen and refresh user state');
		const handle = () => {
			const loginTime = get(store.time);
			// const unLogin = !get(store.token) || !loginTime;
			// const isTimeout = loginTime + 1000 * 60 * 60 * 2 < new Date().getTime();
			// const isTimeShot = loginTime + 1000 * 60 * 115 > new Date().getTime();
			// console.log('unLogin: ', unLogin, 'isTimeout: ', isTimeout, 'isTimeShot: ', isTimeShot);
			if (!get(store.token) || !loginTime) return clearInterval(instance);
			if (loginTime + 1000 * 60 * 60 * 2 < new Date().getTime()) return store.clearLoginState(); // 大于2小时算超时, 清除用户信息
			if (loginTime + 1000 * 60 * 115 > new Date().getTime()) return; // 小于110分钟不处理
			store.refreshLogin();
		};
		handle();
		instance = setInterval(handle, 1000 * 30);
	};
	const throttleRefresh = throttle((token) => {
		if (token) refresh();
		else if (instance) clearInterval(instance);
		// setInterval(() => {
		// 	if (instance) console.log('listening...');
		// }, 5 * 1000);
	}, 500);
	store.token.subscribe(throttleRefresh);
};
